<template>
<div>
  <div class="canvas canvas-task-viewer" ref="canvas"></div>
  <div class="button-group-right">
    <a-icon type="environment" class="bpmn-button" @click="handleReset" />
    <a-icon type="zoom-in" class="bpmn-button mt-2" @click="handleIn" />
    <a-icon type="zoom-out" class="bpmn-button" @click="handleOut" />
    <a-icon type="download" class="bpmn-button mt-2" @click="handleDownload" />
  </div>
</div>

</template>

<script>
// 这里只需要预览引入Viewer就可以，如果需要编辑则引入"bpmn-js/lib/Modeler",并且还需要引入左侧编辑栏panel等
import BpmnViewer from 'bpmn-js/lib/Viewer'
import MoveCanvasModule from 'diagram-js/lib/navigation/movecanvas'
export default {
  props: {
    xml: {
      type: String,
      require: true
    },
    nodeCodes: {
      type: Object,
      default: () => {
        return {
          success: [], // 审批通过接口
          pending: [], // 待审批节点
          error: [] // 审批未通过节点
        }
      }
    },
    height: {
      type: [Number, String],
      default: 540
    }
  },
  data() {
    return {
      bpmnViewer: null,
      zoom: 1
    }
  },
  mounted() {
    this.init()
  },
  methods: {
    init() {
      // 初始时清除图层
      this.bpmnViewer && this.bpmnViewer.destroy()
      this.$refs.canvas.innerHTML = ''
      this.zoom = 1 // 放大缩小比例
      // 初始化canvas
      this.bpmnViewer = new BpmnViewer({
        container: this.$refs.canvas,
        height: this.height, // 根据实际情况设置高度，宽度的话设置父元素的宽度就可以，会自适应的
        additionalModules: [
          MoveCanvasModule
        ]
      })
      if (this.xml) {
        const self = this
        const bpmnXmlStr = this.xml // 从接口获取的xml文件
        this.bpmnViewer.importXML(bpmnXmlStr, function(err) {
          if (err) {
            console.error(err)
          } else {
            const canvas = self.bpmnViewer.get('canvas')
            canvas.zoom('fit-viewport', 'auto')
            self.setNodeColor(canvas)
          }
        })
      }
    },
    // 设置高亮颜色的class
    setNodeColor(canvas) {
      if (Object.keys(this.nodeCodes).length > 0) {
        Object.keys(this.nodeCodes).forEach(key => {
          for (let i = 0; i < this.nodeCodes[key].length; i++) {
            canvas.addMarker(this.nodeCodes[key][i], 'node' + key)
          }
        })
      }
    },
    handleIn() {
      this.zoom += 0.1
      var canvas = this.bpmnViewer.get('canvas')
      console.log(canvas)
      canvas.zoom(this.zoom)
    },
    handleOut() {
      this.zoom -= 0.1
      var canvas = this.bpmnViewer.get('canvas')
      canvas.zoom(this.zoom)
    },
    handleReset() {
      this.zoom = 1
      this.bpmnViewer.get('canvas').zoom('fit-viewport', 'auto')
    },
    async handleDownload() {
      const { err, svg } = await this.bpmnViewer.saveSVG()
      // 读取异常时抛出异常
      if (err) {
        return console.error(err)
      }
      const { href, filename } = this.setEncoded('svg', '流程图', svg)
      this.downloadFunc(href, filename)
    },
    // 文件下载方法
    downloadFunc(href, filename) {
      if (href && filename) {
        const a = document.createElement('a')
        a.download = filename // 指定下载的文件名
        a.href = href //  URL对象
        a.click() // 模拟点击
        URL.revokeObjectURL(a.href) // 释放URL 对象
      }
    },
    // 根据所需类型进行转码并返回下载地址
    setEncoded(type, filename = 'diagram', data) {
      const encodedData = encodeURIComponent(data)
      return {
        filename: `${filename}.${type}`,
        href: `data:application/${type === 'svg' ? 'text/xml' : 'bpmn20-xml'};charset=UTF-8,${encodedData}`,
        data: data
      }
    }
  }
}
</script>
<style lang="less">
.nodesuccess {
  .djs-visual {
    > * {
      stroke: rgb(67, 160, 71) !important;
      fill: rgb(200, 230, 201) !important;
      stroke-width: 2px !important;
    }
  }
}
.nodeerror {
  .djs-visual {
    > * {
      stroke: #ff7875 !important;
      fill: #f3b7b6 !important;
      stroke-width: 2px !important;
    }
  }
}

.nodepending {
  .djs-visual {
    > * {
      stroke: rgb(30, 136, 229) !important;
      fill: rgb(187, 222, 251) !important;
      stroke-width: 2px !important;
    }
  }
}

.nodepending,.nodeerror,.nodesuccess{
  .djs-visual {
    > text{
        fill: #000 !important;
        stroke: #000 !important;
        stroke-width: 0px !important;
      }
  }
}

.canvas-task-viewer{
  .bjs-breadcrumbs{
    display: none;
  }
}

.button-group-right{
  flex-direction: column;
  align-items: center;
  position: absolute;
  bottom: 35%;
  right: 15px;
  z-index: 1000;
  height: 23px;
  display: flex;
}
.bpmn-button{
  color: #4e5969;
  background-color: #f2f3f5;
  border: 1px solid transparent;
  font-size: 20px;
  padding: 3px;
}
</style>
